package com.sprouting.personal.service;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sprouting.personal.dao.*;
import com.sprouting.personal.interfaces.common.Constant;
import com.sprouting.personal.model.common.ResultJson;
import com.sprouting.personal.model.entity.*;
import com.sprouting.personal.model.vo.BirthdayPerson;
import com.sprouting.personal.model.vo.MemberFamilyTree;
import com.sprouting.personal.model.vo.MemberFamilyVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 家庭用户
 *
 * @author ：LX（长沙麓谷）
 * @date 创建时间： 2022/8/1 23:33
 */
@Service
@Slf4j
public class MemberFamilyService extends ServiceImpl<MemberFamilyDao, MemberFamily> {

    @Resource
    private MemberFamilyDao memberFamilyDao;
    @Resource
    private JoinDao joinDao;
    @Resource
    private DictDao dictDao;
    @Resource
    private DictGroupDao dictGroupDao;
    @Resource
    private ExpenseMemberDao expenseMemberDao;
    @Resource
    private PsPasswordDao psPasswordDao;
    @Resource
    private DictService dictService;
    @Resource
    private HomeworkDao homeworkDao;
    @Resource
    private HomeworkRecordDao homeworkRecordDao;


    /**
     * 根据主键查询家庭用户
     * @param id 主键
     * @return
     */
    public MemberFamily getMemberFamilyById(String id) {
        return memberFamilyDao.getMemberFamilyById(id);
    }

    /**
     * 根据真实姓名查询成员
     * @param id 成员ID，传了该ID，则会忽略查询该数据
     * @param userId 当前用户ID
     * @param userName 要添加的人员姓名
     * @return
     */
    public MemberFamily getMemberFamilyRepeatQuery(String id, String userId, String userName) {
        return memberFamilyDao.getMemberFamilyRepeatQuery(id, userId, userName);
    }

    /**
     * 保存成员信息
     * @param memberFamily 成员
     * @param join 关系
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveMemberFamily(MemberFamily memberFamily, Join join) {
        memberFamilyDao.insert(memberFamily);
        joinDao.insert(join);
    }

    /**
     * 更新成员信息
     * @param memberFamily 成员
     * @param join 关系
     */
    @Transactional(rollbackFor = Exception.class)
    public void updMemberFamily(MemberFamily memberFamily, Join join) {
        memberFamilyDao.updateById(memberFamily);
        joinDao.updateById(join);
    }

    /**
     * 获取当前登陆用户的家庭成员信息-只查询到子级
     * @param userId 所属用户ID
     * @return
     */
    public List<MemberFamilyVo> getMemberFamilyByUserId(String userId) {
        DictGroup dictGroup = dictGroupDao.getDictGroupByIdAndCode(null, Constant.RetainDictGroup.MEMBER_OF_FAMILY, userId);
        List<Dict> dictList = dictDao.getDictByGroupId(dictGroup.getId(), userId);
        // 减少数据库的查询压力
        List<String> dictIdList = dictList.stream().map(Dict::getId).collect(Collectors.toList());
        List<MemberFamilyVo> memberFamilyVoList = memberFamilyDao.getMemberFamilyByUserId(userId, dictIdList);
        if (CollUtil.isEmpty(memberFamilyVoList)){
            return memberFamilyVoList;
        }

        Map<String, String> collect = dictList.stream().collect(Collectors.toMap(Dict::getId, Dict::getName));
        for (MemberFamilyVo memberFamilyVo : memberFamilyVoList){
            memberFamilyVo.setConnectionTypeName(collect.get(memberFamilyVo.getConnectionTypeId()));
        }

        return memberFamilyVoList;
    }

    /**
     * 获取用户的社交关系，包含家人和其他-只查询到子级
     * @param sourceId 成员ID
     * @param userId 当前用户ID
     * @return
     */
    public List<MemberFamilyVo> getSocialConnectionAll(String sourceId, String userId) {
        return memberFamilyDao.getSocialConnectionAll(sourceId);
        // List<MemberFamilyVo> memberFamilyVoList = memberFamilyDao.getSocialConnectionAll(sourceId);
        // if (CollUtil.isEmpty(memberFamilyVoList)){
        //     return memberFamilyVoList;
        // }

        // // 家庭成员
        // DictGroup dictGroup = dictGroupDao.getDictGroupByIdAndCode(null, Constant.RetainDictGroup.MEMBER_OF_FAMILY, userId);
        // List<Dict> dictList = dictDao.getDictByGroupId(dictGroup.getId(), userId);
        //
        // // 社交关系
        // DictGroup socialConnectionDictGroup = dictGroupDao.getDictGroupByIdAndCode(null, Constant.RetainDictGroup.SOCIAL_NETWORKS_GROUP, userId);
        // List<Dict> socialConnectionDictList = dictDao.getDictByGroupId(socialConnectionDictGroup.getId(), userId);
        //
        // if (CollUtil.isEmpty(dictList)){
        //     dictList = new ArrayList<>();
        // }
        // if (CollUtil.isNotEmpty(socialConnectionDictList)){
        //     dictList.addAll(socialConnectionDictList);
        // }
        //
        // Map<String, String> collect = dictList.stream().collect(Collectors.toMap(Dict::getId, Dict::getName));
        // for (MemberFamilyVo memberFamilyVo : memberFamilyVoList){
        //     memberFamilyVo.setConnectionTypeName(collect.get(memberFamilyVo.getConnectionTypeId()));
        // }
        //
        // return memberFamilyVoList;
    }

    /**
     * 查询当前用户的全部的子级关系信息，包含对应的关系数据
     * @param userId 登录用户Id
     * @return
     */
    public List<MemberFamilyTree> getMemberFamilyJoinByUserIdAll(String userId) {
        return memberFamilyDao.getMemberFamilyJoinByUserIdAll(userId);
    }

    /**
     * 删除家庭成员
     * @param id 家庭成员表ID
     * @param joinId 关系表ID
     * @param userId 登录用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void delMemberFamilyById(String id, String joinId, String userId) {
        memberFamilyDao.deleteById(id);
        joinDao.deleteById(joinId);

        /// 需要对账单中绑定的人员进行更新处理

        // 账目处理，家庭成员中这个人的密码归于全家
        LambdaUpdateWrapper<ExpenseMember> expenseMemberLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        expenseMemberLambdaUpdateWrapper.eq(ExpenseMember::getUserId, userId);
        expenseMemberLambdaUpdateWrapper.eq(ExpenseMember::getFamilyMemberId, id);
        expenseMemberLambdaUpdateWrapper.set(ExpenseMember::getFamilyMemberId, Constant.DefaultValue.STRING);
        expenseMemberDao.update(null, expenseMemberLambdaUpdateWrapper);
        // 密码,家庭成员中这个人的密码归于全家
        LambdaUpdateWrapper<PsPassword> passwordLambdaUpdate = new LambdaUpdateWrapper<>();
        passwordLambdaUpdate.eq(PsPassword::getUserId, userId);
        passwordLambdaUpdate.eq(PsPassword::getUserMemberFamilyId, id);
        passwordLambdaUpdate.set(PsPassword::getUserMemberFamilyId, Constant.DefaultValue.STRING);
        psPasswordDao.update(null, passwordLambdaUpdate);

        // 家庭作业
        // 似乎不需要去处理，当恢复了人员，这个数据自动也就有了
        LambdaUpdateWrapper<Homework> homeworkLambdaUpdate = new LambdaUpdateWrapper<>();
        homeworkLambdaUpdate.eq(Homework::getMemberFamilyId, id);
        homeworkLambdaUpdate.eq(Homework::getUserId, userId);
        homeworkLambdaUpdate.set(Homework::getUpdateTime, new Date());
        homeworkLambdaUpdate.set(Homework::getDelType, Constant.DelType.DEL);
        homeworkDao.update(null, homeworkLambdaUpdate);
        // 作业记录
        LambdaUpdateWrapper<HomeworkRecord> homeworkRecordLambdaUpdate = new LambdaUpdateWrapper<>();
        homeworkRecordLambdaUpdate.eq(HomeworkRecord::getMemberFamilyId, id);
        homeworkRecordLambdaUpdate.eq(HomeworkRecord::getUserId, userId);
        homeworkRecordLambdaUpdate.set(HomeworkRecord::getUpdateTime, new Date());
        homeworkRecordLambdaUpdate.set(HomeworkRecord::getDelType, Constant.DelType.DEL);
        homeworkRecordDao.update(null, homeworkRecordLambdaUpdate);
    }

    /**
     * 根据登录用户ID查询全部成员
     * 过滤掉不开启生日提醒的，不过滤掉过世的，有时候过世人员需要进行拜祭
     * @param userId 当前用户ID
     * @return
     */
    public List<BirthdayPerson> getMemberFamilyByUserIdAll(String userId) {
        return memberFamilyDao.getMemberFamilyByUserIdAll(userId);
    }

    /**
     * 根据身份证查询人员
     * @param id 主键，传则忽略该ID
     * @param userId 登录用户ID
     * @param idCard 身份证
     * @return
     */
    public MemberFamily getMemberFamilyByIdCard(String id, String userId, String idCard) {
        return memberFamilyDao.getMemberFamilyByIdCard(id, userId, idCard);
    }

    /**
     * 根据主键查询用户，与上面的方法相比，会将一些关联信息查询出来
     * @param id 用户ID
     * @return
     */
    public MemberFamilyVo getMemberFamilyByIdJoin(String id) {
        return memberFamilyDao.getMemberFamilyByIdJoin(id);
    }

    /**
     * 根据用户ID查询全部的节点
     * @param userId 用户ID
     * @return
     */
    public List<MemberFamily> getDiagramNode(String userId) {
        return memberFamilyDao.getDiagramNode(userId);
    }

    /**
     * 获取陵墓信息
     * @param page 分页参数
     * @param userId 登录用户ID
     * @return
     */
    public Page<MemberFamilyVo> getTombListPage(Page page, String userId) {
        return memberFamilyDao.getTombListPage(page, userId);
    }

    /**
     * 统计当前用户存在多少条数据
     * @param userId 登录用户ID
     * @return
     */
    public Long getMemberFamilyTotal(String userId) {
        return memberFamilyDao.getMemberFamilyTotal(userId);
    }

    /**
     * 获取子女信息
     * @param userId 登录用户ID
     * @return
     */
    public List<MemberFamilyVo> getSonInfo(String userId) {
        // 找到家庭成员
        List<Dict> dictList = dictService.getType(Constant.RetainDictGroup.MEMBER_OF_FAMILY, StpUtil.getLoginIdAsString());
        if (CollUtil.isEmpty(dictList)){
            return null;
        }
        Dict dict = dictList.stream().filter(obj -> Constant.MemberType.SON.equals(obj.getCode())).findFirst().orElse(null);
        if (dict == null){
            return null;
        }

        return memberFamilyDao.getMemberFamilyByUserId(userId, ListUtil.of(dict.getId()));
    }
}
